﻿/*
**  ContactNode
*/
if (!$.Engine.Dynamic || typeof $.Engine.Dynamic === "undefined") $.Engine.Dynamic = {};
if (!$.Engine.Dynamic.Contact || typeof $.Engine.Dynamic.Contact === "undefined") $.Engine.Dynamic.Contact = {};
$.Engine.Dynamic.Contact.Contact=function (s1, s2) {
  this.m_node1 = new $.Engine.Dynamic.Contact.ContactNode();
  this.m_node2 = new $.Engine.Dynamic.Contact.ContactNode();
  this.m_flags = 0;

  if (!s1 || !s2) {
    this.m_shape1 = null;
    this.m_shape2 = null;
    return;
  }

  this.m_shape1 = s1;
  this.m_shape2 = s2;

  this.m_manifoldCount = 0;

  this.m_friction = Math.sqrt(this.m_shape1.m_friction * this.m_shape2.m_friction);
  this.m_restitution = $.Engine.Math.Max(this.m_shape1.m_restitution, this.m_shape2.m_restitution);

  this.m_prev = null;
  this.m_next = null;

  this.m_node1.contact = null;
  this.m_node1.prev = null;
  this.m_node1.next = null;
  this.m_node1.other = null;

  this.m_node2.contact = null;
  this.m_node2.prev = null;
  this.m_node2.next = null;
  this.m_node2.other = null;
};

Object.extend($.Engine.Dynamic.Contact.Contact.prototype, {
  GetManifolds: function () { return null },
  GetManifoldCount: function () {
    return this.m_manifoldCount;
  },

  GetNext: function () {
    return this.m_next;
  },

  GetShape1: function () {
    return this.m_shape1;
  },

  GetShape2: function () {
    return this.m_shape2;
  },

  Evaluate: function () { },

  m_flags: 0,

  // World pool and list pointers.
  m_prev: null,
  m_next: null,

  // Nodes for connecting bodies.
  m_node1: new $.Engine.Dynamic.Contact.ContactNode(),
  m_node2: new $.Engine.Dynamic.Contact.ContactNode(),

  m_shape1: null,
  m_shape2: null,

  m_manifoldCount: 0,

  // Combined friction
  m_friction: null
});
$.Engine.Dynamic.Contact.Contact.e_islandFlag = 0x0001;
$.Engine.Dynamic.Contact.Contact.e_destroyFlag = 0x0002;
$.Engine.Dynamic.Contact.Contact.s_registers = null;
$.Engine.Dynamic.Contact.Contact.s_initialized = false;

$.Engine.Dynamic.Contact.Contact.AddType = function (createFcn, destroyFcn, type1, type2) {
  this.s_registers[type1][type2].createFcn = createFcn;
  this.s_registers[type1][type2].destroyFcn = destroyFcn;
  this.s_registers[type1][type2].primary = true;

  if (type1 != type2) {
    this.s_registers[type2][type1].createFcn = createFcn;
    this.s_registers[type2][type1].destroyFcn = destroyFcn;
    this.s_registers[type2][type1].primary = false;
  }
};
$.Engine.Dynamic.Contact.Contact.InitializeRegisters = function () {
  $.Engine.Dynamic.Contact.Contact.s_registers = new Array($.Engine.Collision.Shape.Shape.e_shapeTypeCount);
  for (var i = 0; i < $.Engine.Collision.Shape.Shape.e_shapeTypeCount; i++) {
    $.Engine.Dynamic.Contact.Contact.s_registers[i] = new Array($.Engine.Collision.Shape.Shape.e_shapeTypeCount);
    for (var j = 0; j < $.Engine.Collision.Shape.Shape.e_shapeTypeCount; j++) {
      $.Engine.Dynamic.Contact.Contact.s_registers[i][j] = new $.Engine.Dynamic.Contact.ContactRegister();
    }
  }

  //this.AddType(b2CircleContact.Create, b2CircleContact.Destroy, $.Engine.Collision.Shape.Shape.e_circleShape, $.Engine.Collision.Shape.Shape.e_circleShape);
  //this.AddType(b2PolyAndCircleContact.Create, b2PolyAndCircleContact.Destroy, $.Engine.Collision.Shape.Shape.e_polyShape, $.Engine.Collision.Shape.Shape.e_circleShape);
  this.AddType($.Engine.Dynamic.Contact.PolyContact.Create, $.Engine.Dynamic.Contact.PolyContact.Destroy, $.Engine.Collision.Shape.Shape.e_polyShape, $.Engine.Collision.Shape.Shape.e_polyShape);

};

$.Engine.Dynamic.Contact.Contact.Create = function (shape1, shape2, allocator) {
  if ($.Engine.Dynamic.Contact.Contact.s_initialized == false) {
    $.Engine.Dynamic.Contact.Contact.InitializeRegisters();
    $.Engine.Dynamic.Contact.Contact.s_initialized = true;
  }

  var type1 = shape1.m_type;
  var type2 = shape2.m_type;

  var createFcn = $.Engine.Dynamic.Contact.Contact.s_registers[type1][type2].createFcn;
  if (createFcn) {
    if ($.Engine.Dynamic.Contact.Contact.s_registers[type1][type2].primary) {
      return createFcn(shape1, shape2, allocator);
    }
    else {
      var c = createFcn(shape2, shape1, allocator);
      for (var i = 0; i < c.GetManifoldCount(); ++i) {
        var m = c.GetManifolds()[i];
        m.normal = m.normal.Negative();
      }
      return c;
    }
  }
  else {
    return null;
  }
};
$.Engine.Dynamic.Contact.Contact.Destroy = function (contact, allocator) {
  if (contact.GetManifoldCount() > 0) {
    contact.m_shape1.m_body.WakeUp();
    contact.m_shape2.m_body.WakeUp();
  }

  var type1 = contact.m_shape1.m_type;
  var type2 = contact.m_shape2.m_type;

  var destroyFcn = this.s_registers[type1][type2].destroyFcn;
  destroyFcn(contact, allocator);
};